//! HTTP请求处理器模块
//! 
//! 这个模块包含了所有的HTTP请求处理器，包括：
//! - 健康检查处理器
//! - 认证相关处理器
//! - 用户管理处理器

use axum::{
    extract::{Path, Query, State},
    http::StatusCode,
    response::Json,
    middleware,
};
use uuid::Uuid;
use serde_json::json;

use crate::{
    models::{
        ApiResponse, UserInfo, CreateUserRequest, UpdateUserRequest, LoginRequest, LoginResponse,
        UserQuery, PaginatedResponse, HealthCheckResponse, ServiceCheck,
    },
    errors::{AppError, AppResult},
    AppState,
};

/// 健康检查处理器
pub mod health {
    use super::*;

    /// 根路径处理器
    pub async fn root() -> &'static str {
        "🚀 Rust Web服务演示项目运行中！\n\n可用的端点：\n- GET /health - 健康检查\n- POST /api/v1/auth/register - 用户注册\n- POST /api/v1/auth/login - 用户登录\n- GET /api/v1/auth/me - 获取当前用户信息\n- GET /api/v1/users - 获取用户列表\n- GET /ws - WebSocket连接\n- GET /metrics - Prometheus指标"
    }

    /// 健康检查处理器
    pub async fn health_check(State(state): State<AppState>) -> Json<ApiResponse<HealthCheckResponse>> {
        let mut checks = std::collections::HashMap::new();
        let mut overall_status = "healthy";

        // 检查数据库
        match state.db.health_check().await {
            Ok(_) => {
                checks.insert("database".to_string(), ServiceCheck {
                    status: "healthy".to_string(),
                    response_time_ms: None,
                    error: None,
                    details: None,
                });
            }
            Err(e) => {
                overall_status = "unhealthy";
                checks.insert("database".to_string(), ServiceCheck {
                    status: "unhealthy".to_string(),
                    response_time_ms: None,
                    error: Some(e.to_string()),
                    details: None,
                });
            }
        }

        // 检查Redis
        match state.cache.health_check().await {
            Ok(_) => {
                checks.insert("redis".to_string(), ServiceCheck {
                    status: "healthy".to_string(),
                    response_time_ms: None,
                    error: None,
                    details: None,
                });
            }
            Err(e) => {
                overall_status = "unhealthy";
                checks.insert("redis".to_string(), ServiceCheck {
                    status: "unhealthy".to_string(),
                    response_time_ms: None,
                    error: Some(e.to_string()),
                    details: None,
                });
            }
        }

        // 检查连接状态
        let websocket_count = state.websocket.get_online_users_count().await;
        let (tcp_total, tcp_active) = (0, 0); // TCP连接统计暂时设为0

        let mut connection_details = std::collections::HashMap::new();
        connection_details.insert("websocket_connections".to_string(), json!(websocket_count));
        connection_details.insert("tcp_total_connections".to_string(), json!(tcp_total));
        connection_details.insert("tcp_active_connections".to_string(), json!(tcp_active));

        checks.insert("connections".to_string(), ServiceCheck {
            status: if websocket_count > 1000 || tcp_total > 1000 { "warning" } else { "healthy" }.to_string(),
            response_time_ms: None,
            error: None,
            details: Some(connection_details),
        });

        let health_response = HealthCheckResponse {
            status: overall_status.to_string(),
            version: env!("CARGO_PKG_VERSION").to_string(),
            timestamp: chrono::Utc::now(),
            checks,
        };

        Json(ApiResponse::success(health_response))
    }
}

/// 认证相关处理器
pub mod auth {
    use super::*;
    use crate::models::Claims;

    /// 用户注册处理器
    pub async fn register(
        State(state): State<AppState>,
        Json(request): Json<CreateUserRequest>,
    ) -> Result<Json<ApiResponse<UserInfo>>, AppError> {
        tracing::info!("📝 用户注册请求: {}", request.email);

        // 验证请求数据
        validate_create_user_request(&request)?;

        // 创建用户
        let user = state.db.create_user(request).await?;

        // 缓存用户信息
        if let Err(e) = state.cache.cache_user(&user, Some(3600)).await {
            tracing::warn!("⚠️ 缓存用户信息失败: {}", e);
        }

        let user_info: UserInfo = user.into();

        tracing::info!("✅ 用户注册成功: {}", user_info.username);
        Ok(Json(ApiResponse::success(user_info)))
    }

    /// 用户登录处理器
    pub async fn login(
        State(state): State<AppState>,
        Json(request): Json<LoginRequest>,
    ) -> Result<Json<ApiResponse<LoginResponse>>, AppError> {
        tracing::info!("🔐 用户登录请求: {}", request.email_or_username);

        // 执行登录
        let login_response = state.auth.login(&request.email_or_username, &request.password).await?;

        // 创建会话
        let session_id = Uuid::new_v4().to_string();
        if let Err(e) = state.cache.cache_session(&session_id, login_response.user.id, 86400).await {
            tracing::warn!("⚠️ 缓存会话失败: {}", e);
        }

        tracing::info!("✅ 用户登录成功: {}", login_response.user.username);
        Ok(Json(ApiResponse::success(login_response)))
    }

    /// 用户登出处理器
    pub async fn logout(
        State(state): State<AppState>,
        headers: axum::http::HeaderMap,
    ) -> Result<Json<ApiResponse<()>>, AppError> {
        // 从Authorization头中提取令牌
        let auth_header = headers
            .get("authorization")
            .and_then(|h| h.to_str().ok())
            .ok_or(AppError::Unauthorized)?;

        let token = state.auth.extract_token_from_header(auth_header)?;
        let claims = state.auth.verify_token(&token)?;

        // 删除会话缓存（如果有的话）
        // 这里简化处理，实际应用中应该有更复杂的会话管理

        tracing::info!("🚪 用户登出: {}", claims.username);
        Ok(Json(ApiResponse::success(())))
    }

    /// 获取当前用户信息处理器
    pub async fn get_current_user(
        State(state): State<AppState>,
        headers: axum::http::HeaderMap,
    ) -> Result<Json<ApiResponse<UserInfo>>, AppError> {
        // 从Authorization头中提取令牌
        let auth_header = headers
            .get("authorization")
            .and_then(|h| h.to_str().ok())
            .ok_or(AppError::Unauthorized)?;

        let token = state.auth.extract_token_from_header(auth_header)?;
        let user_info = state.auth.verify_and_get_user(&token).await?;

        Ok(Json(ApiResponse::success(user_info)))
    }

    /// 验证用户创建请求
    pub(crate) fn validate_create_user_request(request: &CreateUserRequest) -> AppResult<()> {
        if request.username.is_empty() || request.username.len() < 3 {
            return Err(AppError::validation("用户名长度至少3个字符"));
        }

        if request.email.is_empty() || !request.email.contains('@') {
            return Err(AppError::validation("邮箱格式无效"));
        }

        if request.password.is_empty() || request.password.len() < 8 {
            return Err(AppError::validation("密码长度至少8个字符"));
        }

        if request.password != request.confirm_password {
            return Err(AppError::validation("密码和确认密码不匹配"));
        }

        Ok(())
    }
}

/// 用户管理处理器
pub mod users {
    use super::*;

    /// 获取用户列表处理器
    pub async fn get_users(
        State(state): State<AppState>,
        headers: axum::http::HeaderMap,
        Query(query): Query<UserQuery>,
    ) -> Result<Json<ApiResponse<PaginatedResponse<UserInfo>>>, AppError> {
        // 验证用户权限
        verify_admin_access(&state, &headers).await?;

        tracing::info!("📋 获取用户列表请求");

        // 从数据库获取用户列表
        let paginated_users = state.db.get_users(query).await?;

        // 转换为UserInfo
        let user_infos: Vec<UserInfo> = paginated_users.data.into_iter().map(|u| u.into()).collect();

        let response = PaginatedResponse::new(
            user_infos,
            paginated_users.pagination.page,
            paginated_users.pagination.limit,
            paginated_users.pagination.total,
        );

        Ok(Json(ApiResponse::success(response)))
    }

    /// 获取单个用户信息处理器
    pub async fn get_user(
        State(state): State<AppState>,
        headers: axum::http::HeaderMap,
        Path(user_id): Path<Uuid>,
    ) -> Result<Json<ApiResponse<UserInfo>>, AppError> {
        // 验证用户权限
        let current_user = verify_user_access(&state, &headers).await?;

        // 检查是否是管理员或查看自己的信息
        if current_user.id != user_id && current_user.role != crate::models::UserRole::Admin {
            return Err(AppError::Forbidden);
        }

        tracing::info!("👤 获取用户信息请求: {}", user_id);

        // 先从缓存获取
        if let Ok(Some(user)) = state.cache.get_cached_user(user_id).await {
            tracing::debug!("✅ 从缓存获取用户信息: {}", user_id);
            return Ok(Json(ApiResponse::success(user.into())));
        }

        // 从数据库获取
        let user = state.db.get_user_by_id(user_id).await?
            .ok_or(AppError::NotFound)?;

        // 缓存用户信息
        if let Err(e) = state.cache.cache_user(&user, Some(3600)).await {
            tracing::warn!("⚠️ 缓存用户信息失败: {}", e);
        }

        Ok(Json(ApiResponse::success(user.into())))
    }

    /// 更新用户信息处理器
    pub async fn update_user(
        State(state): State<AppState>,
        headers: axum::http::HeaderMap,
        Path(user_id): Path<Uuid>,
        Json(request): Json<UpdateUserRequest>,
    ) -> Result<Json<ApiResponse<UserInfo>>, AppError> {
        // 验证用户权限
        let current_user = verify_user_access(&state, &headers).await?;

        // 检查是否是管理员或更新自己的信息
        if current_user.id != user_id && current_user.role != crate::models::UserRole::Admin {
            return Err(AppError::Forbidden);
        }

        // 非管理员不能修改角色和状态
        let mut update_request = request;
        if current_user.role != crate::models::UserRole::Admin {
            update_request.role = None;
            update_request.status = None;
        }

        tracing::info!("✏️ 更新用户信息请求: {}", user_id);

        // 更新用户信息
        let updated_user = state.db.update_user(user_id, update_request).await?;

        // 更新缓存
        if let Err(e) = state.cache.update_cached_user(&updated_user, Some(3600)).await {
            tracing::warn!("⚠️ 更新用户缓存失败: {}", e);
        }

        Ok(Json(ApiResponse::success(updated_user.into())))
    }

    /// 删除用户处理器
    pub async fn delete_user(
        State(state): State<AppState>,
        headers: axum::http::HeaderMap,
        Path(user_id): Path<Uuid>,
    ) -> Result<Json<ApiResponse<()>>, AppError> {
        // 验证管理员权限
        verify_admin_access(&state, &headers).await?;

        tracing::info!("🗑️ 删除用户请求: {}", user_id);

        // 删除用户
        state.db.delete_user(user_id).await?;

        // 删除缓存
        if let Err(e) = state.cache.delete_cached_user(user_id).await {
            tracing::warn!("⚠️ 删除用户缓存失败: {}", e);
        }

        Ok(Json(ApiResponse::success(())))
    }

    /// 验证用户访问权限
    async fn verify_user_access(
        state: &AppState,
        headers: &axum::http::HeaderMap,
    ) -> AppResult<UserInfo> {
        let auth_header = headers
            .get("authorization")
            .and_then(|h| h.to_str().ok())
            .ok_or(AppError::Unauthorized)?;

        let token = state.auth.extract_token_from_header(auth_header)?;
        state.auth.verify_and_get_user(&token).await
    }

    /// 验证管理员访问权限
    async fn verify_admin_access(
        state: &AppState,
        headers: &axum::http::HeaderMap,
    ) -> AppResult<UserInfo> {
        let user = verify_user_access(state, headers).await?;

        if user.role != crate::models::UserRole::Admin {
            return Err(AppError::Forbidden);
        }

        Ok(user)
    }
}

/// 通用处理器工具函数
pub mod utils {
    use super::*;

    /// 提取请求ID
    pub fn extract_request_id(headers: &axum::http::HeaderMap) -> Option<String> {
        headers
            .get("x-request-id")
            .and_then(|h| h.to_str().ok())
            .map(|s| s.to_string())
    }

    /// 获取客户端IP
    pub fn get_client_ip(headers: &axum::http::HeaderMap) -> Option<String> {
        headers
            .get("x-forwarded-for")
            .or_else(|| headers.get("x-real-ip"))
            .and_then(|h| h.to_str().ok())
            .map(|s| s.to_string())
    }

    /// 记录请求日志
    pub fn log_request(
        method: &str,
        path: &str,
        status: StatusCode,
        duration: std::time::Duration,
        request_id: Option<String>,
    ) {
        let duration_ms = duration.as_millis();
        let request_id = request_id.unwrap_or_else(|| "unknown".to_string());

        tracing::info!(
            "{} {} {} {}ms [{}]",
            method,
            path,
            status.as_u16(),
            duration_ms,
            request_id
        );
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_validate_create_user_request() {
        let valid_request = CreateUserRequest {
            username: "testuser".to_string(),
            email: "test@example.com".to_string(),
            password: "password123".to_string(),
            confirm_password: "password123".to_string(),
            full_name: Some("Test User".to_string()),
        };

        assert!(auth::validate_create_user_request(&valid_request).is_ok());

        let invalid_request = CreateUserRequest {
            username: "ab".to_string(), // 太短
            email: "invalid-email".to_string(),
            password: "123".to_string(), // 太短
            confirm_password: "456".to_string(), // 不匹配
            full_name: None,
        };

        assert!(auth::validate_create_user_request(&invalid_request).is_err());
    }

    #[test]
    fn test_extract_request_id() {
        let mut headers = axum::http::HeaderMap::new();
        headers.insert("x-request-id", "test-request-id".parse().unwrap());

        let request_id = utils::extract_request_id(&headers);
        assert_eq!(request_id, Some("test-request-id".to_string()));
    }

    #[test]
    fn test_get_client_ip() {
        let mut headers = axum::http::HeaderMap::new();
        headers.insert("x-forwarded-for", "192.168.1.1".parse().unwrap());

        let ip = utils::get_client_ip(&headers);
        assert_eq!(ip, Some("192.168.1.1".to_string()));
    }
}
